<template>
  <div class="system-dic-container layout-padding">
    <el-card shadow="hover" class="mb5" body-class="pa5">
      <el-row>
        <el-col :xs="24" :sm="8" :md="6" :lg="6" :xl="4" class="pa5">
          <el-input clearable v-model="filterText" placeholder="查询菜单" :prefix-icon="Search" />
        </el-col>
        <el-col :xs="24" :sm="6" :md="4" :lg="4" :xl="4" class="pa5">
          <el-select v-model="params.object_type" placeholder="选择类型" @change="onChangeType">
            <el-option label="按角色" :value="0" />
            <el-option label="按用户" :value="1" />
            <el-option label="全部用户" :value="9" />
          </el-select>
        </el-col>
        <el-col
          :xs="24"
          :sm="12"
          :md="8"
          :lg="8"
          :xl="6"
          class="pa5"
          v-if="params.object_type === 0"
        >
          <el-select
            clearable
            filterable
            v-model="params.object_id"
            placeholder="请选择角色"
            @change="onFetch"
          >
            <el-option
              v-for="(item, index) in roleItems"
              :key="index"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-col>
        <el-col
          :xs="24"
          :sm="12"
          :md="8"
          :lg="8"
          :xl="6"
          class="pa5"
          v-else-if="params.object_type === 1"
        >
          <el-tree-select
            clearable
            filterable
            :data="userItems"
            default-expand-all
            v-model="params.object_id"
            @change="onFetch"
            placeholder="请选择用户"
          />
        </el-col>
        <el-col :xs="24" :sm="8" :md="6" :lg="6" :xl="4" class="pa5">
          <el-button
            type="primary"
            :icon="Search"
            :loading="loading"
            @click="onFetch"
            class="ml-auto"
            :disabled="!params.object_id && params.object_type !== 9"
          >
            查询
          </el-button>
        </el-col>
      </el-row>
    </el-card>
    <div class="pa10 layout-padding-auto layout-padding-view">
      <el-scrollbar>
        <el-tree
          style="min-width: 500px; max-width: 1000px"
          ref="treeRef"
          :data="items"
          :props="{
            children: 'children',
            label: 'title',
            value: 'id'
          }"
          node-key="id"
          default-expand-all
          :filter-node-method="filterNode"
          show-checkbox
          @check="onTreeCheck"
        >
          <template #default="{ node, data }">
            <div class="custom-tree-node flex flex-grow">
              <span>{{ node.label }}</span>
              <el-tag v-if="data.is_hide" type="warning" class="ml10" size="small">隐藏</el-tag>
              <div class="ml-auto mr20" @click.stop="" v-if="data.actions.length">
                <el-checkbox
                  v-for="(item, index) in data.actions"
                  :key="index"
                  v-model="item.authorization"
                  :label="item.name"
                  :disabled="!data.authorization"
                  border
                  size="small"
                  class="mr3"
                  @change="onCheck(data)"
                />
                <el-checkbox
                  v-model="data.checkAll"
                  :indeterminate="data.indeterminate"
                  :disabled="!data.authorization"
                  label="全部"
                  border
                  size="small"
                  class="mr3"
                  @change="onCheckAll(data)"
                />
              </div>
            </div>
          </template>
        </el-tree>
        <div style="height: 100px; width: 100%"></div>
      </el-scrollbar>
    </div>
  </div>
</template>

<script setup lang="ts" name="systemPermission">
import { nextTick, onMounted, reactive, ref, watch } from 'vue'
import { useBaseRoleApi } from '@/api/base/role'
import { useBasePermissionApi } from '@/api/base/permission'
import { useBaseApi } from '@/api/base'
import { eachTree, toArrayTree } from 'xe-utils'
import { Search } from '@element-plus/icons-vue'
import { useI18n } from 'vue-i18n'
import type { BaseGetPermissionsType } from '@/api/base/permission'

// 定义变量内容
const { search_all_users } = useBaseApi()
const { GetBaseRoleList } = useBaseRoleApi()
const { GetBasePermissions, SaveBasePermissions } = useBasePermissionApi()

interface UserRoleType {
  id: string
  name: string
  descript: string
  users_id: string[]
  userse_name: string[]
  user_count: number
}

const { t } = useI18n()
const treeRef = ref()
const loading = ref(false)
const roleItems = ref<UserRoleType[]>([])
const userItems = ref<UserRoleType[]>([])
const params = reactive({
  cat: 0,
  object_type: 0, // 0 角色 1 用户
  object_id: '' // 用户或角色ID
})
const items = ref<BaseGetPermissionsType[]>([])
const filterText = ref('')

const filterNode = (value: string, data: any) => {
  if (!value) return true
  return data.title.includes(value)
}

/**
 * 类型改变
 */
const onChangeType = () => {
  params.object_id = params.object_type === 9 ? 'ALL' : ''
  if (params.object_type === 9) {
    onFetch()
  } else {
    items.value = []
  }
}

// 查询菜单
const onFetch = () => {
  loading.value = true
  GetBasePermissions(params)
    .then(({ data }) => {
      const keys: string[] = []
      data.forEach((v) => {
        v.title = t(v.title)
        if (v.authorization) {
          keys.push(v.id)
        }
        v.checkAll = v.actions.every((e) => e.authorization)
        v.indeterminate = v.actions.some((s) => s.authorization) && !v.checkAll
      })
      items.value = toArrayTree(data, { parentKey: 'pid', sortKey: 'idx' })

      nextTick(() => {
        treeRef.value.setCheckedKeys(keys)
      })
    })
    .finally(() => (loading.value = false))
}

/**
 * 树选中
 * @param row
 */
const onTreeCheck = (row: BaseGetPermissionsType) => {
  const keys = treeRef.value.getCheckedKeys()
  row.authorization = keys.includes(row.id)
  if (row.children.length) {
    const rows: BaseGetPermissionsType[] = []
    eachTree(row.children, (item) => {
      if (item.children.length === 0) {
        item.authorization = row.authorization
        rows.push(item)
      }
    })
    onSave(rows)
  } else {
    onSave([row])
  }
}

/**
 * checkbox选中
 * @param row
 */
const onCheck = (row: BaseGetPermissionsType) => {
  row.checkAll = row.actions.every((e) => e.authorization)
  row.indeterminate = row.actions.some((s) => s.authorization) && !row.checkAll
  onSave([row])
}

/**
 * checkbox全选
 * @param row
 */
const onCheckAll = (row: BaseGetPermissionsType) => {
  if (row.checkAll) {
    row.actions.forEach((v) => {
      v.authorization = true
    })
  } else {
    row.actions.forEach((v) => {
      v.authorization = false
    })
  }
  onSave([row])
  row.indeterminate = false
}

// 保存
const onSave = async (rows: BaseGetPermissionsType[]) => {
  loading.value = true
  for (const item of rows) {
    const actions = item.actions.filter((f) => f.authorization).map((v) => v.action)
    await SaveBasePermissions({
      object_type: params.object_type,
      object_id: params.object_id,
      id: item.id,
      authorization: item.authorization,
      actions: actions
      // "actions": row.authorization ? actions : []
    }).finally(() => (loading.value = false))
  }
  loading.value = false
}

/**
 * 查询列表
 */
const onFetchDefault = () => {
  GetBaseRoleList().then(({ data }) => {
    roleItems.value = data
    if (data.length) {
      params.object_id = data[0].id
      onFetch()
    }
  })
  search_all_users({
    status_dis: 0,
    status_leave: 0
  }).then(({ data }) => {
    const { deps, users } = data
    users.forEach((user) => {
      user.isUser = true
      user.value = user.id
      user.label = user.name
    })
    deps.forEach((dep) => {
      const items = users.filter((user) => user['dep_id'] === dep.id)
      dep.value = dep.id
      dep.label = `${dep.name}[${items.length}人]`
      dep.disabled = !deps.some((s) => s.pid === dep.id) && !items.length
      items.forEach((user) => {
        user.pid = dep.id
      })
    })
    userItems.value = toArrayTree(deps.concat(users), { parentKey: 'pid' })
  })
}

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

// 页面加载时
onMounted(() => {
  onFetchDefault()
})
</script>
